{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "骆昊正在学习Python程序设计.\n",
      "骆昊正在观看岛国爱情动作片.\n",
      "王大锤正在学习思想品德.\n",
      "王大锤只能观看《熊出没》.\n"
     ]
    }
   ],
   "source": [
    "class Student(object):\n",
    "    # __init__是一个特殊方法用于在创建对象时进行初始化操作\n",
    "    # 通过这个方法我们可以为学生对象绑定name和age两个属性\n",
    "    def __init__(self, name, age):\n",
    "        self.name = name\n",
    "        self.age = age\n",
    "    def study(self, course_name):\n",
    "        print('%s正在学习%s.' % (self.name, course_name))\n",
    "    # PEP 8要求标识符的名字用全小写多个单词用下划线连接\n",
    "    # 但是很多程序员和公司更倾向于使用驼峰命名法(驼峰标识)\n",
    "    def watch_av(self):\n",
    "        if self.age < 18:\n",
    "            print('%s只能观看《熊出没》.' % self.name)\n",
    "        else:\n",
    "            print('%s正在观看岛国爱情动作片.' % self.name)\n",
    "def main():\n",
    "    # 创建学生对象并指定姓名和年龄\n",
    "    stu1 = Student('骆昊', 38)\n",
    "    # 给对象发study消息\n",
    "    stu1.study('Python程序设计')\n",
    "    # 给对象发watch_av消息\n",
    "    stu1.watch_av()\n",
    "    stu2 = Student('王大锤', 15)\n",
    "    stu2.study('思想品德')\n",
    "    stu2.watch_av()\n",
    "\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    main()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "ename": "AttributeError",
     "evalue": "'Test' object has no attribute '__foo'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[1;32mD:\\temp/ipykernel_19844/351949448.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m     14\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     15\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0m__name__\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;34m\"__main__\"\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 16\u001b[1;33m     \u001b[0mmain\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32mD:\\temp/ipykernel_19844/351949448.py\u001b[0m in \u001b[0;36mmain\u001b[1;34m()\u001b[0m\n\u001b[0;32m     11\u001b[0m     \u001b[1;31m#test.__bar()\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     12\u001b[0m     \u001b[1;31m# AttributeError: 'Test' object has no attribute '__foo'\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 13\u001b[1;33m     \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__foo\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     14\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     15\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0m__name__\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;34m\"__main__\"\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mAttributeError\u001b[0m: 'Test' object has no attribute '__foo'"
     ]
    }
   ],
   "source": [
    "class Test:\n",
    "    def __init__(self, foo):\n",
    "        self.__foo = foo\n",
    "    def __bar(self):\n",
    "        print(self.__foo)\n",
    "        print('__bar')\n",
    "\n",
    "def main():\n",
    "    test = Test('hello')\n",
    "    # AttributeError: 'Test' object has no attribute '__bar'\n",
    "    test.__bar()\n",
    "    # AttributeError: 'Test' object has no attribute '__foo'\n",
    "    print(test.__foo)\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    main()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello\n",
      "__bar\n",
      "hello\n"
     ]
    }
   ],
   "source": [
    "class Test:\n",
    "    def __init__(self, foo):\n",
    "        self.__foo = foo\n",
    "\n",
    "    def __bar(self):\n",
    "        print(self.__foo)\n",
    "        print('__bar')\n",
    "\n",
    "def main():\n",
    "    test = Test('hello')\n",
    "    test._Test__bar()\n",
    "    print(test._Test__foo)\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    main()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "23:59:58\n"
     ]
    },
    {
     "ename": "NameError",
     "evalue": "name 'sleep' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32mD:\\temp/ipykernel_19844/3108693450.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m     30\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     31\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0m__name__\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;34m'__main__'\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 32\u001b[1;33m     \u001b[0mmain\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32mD:\\temp/ipykernel_19844/3108693450.py\u001b[0m in \u001b[0;36mmain\u001b[1;34m()\u001b[0m\n\u001b[0;32m     26\u001b[0m     \u001b[1;32mwhile\u001b[0m \u001b[1;32mTrue\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     27\u001b[0m         \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mclock\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mshow\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 28\u001b[1;33m         \u001b[0msleep\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     29\u001b[0m         \u001b[0mclock\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrun\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     30\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mNameError\u001b[0m: name 'sleep' is not defined"
     ]
    }
   ],
   "source": [
    "class Clock(object):\n",
    "    \"\"\"数字时钟\"\"\"\n",
    "\n",
    "    def __init__(self, hour=0, minute=0, second=0):\n",
    "        \"\"\"初始化方法\n",
    "        :param hour: 时\n",
    "        :param minute: 分\n",
    "        :param second: 秒\n",
    "        \"\"\"\n",
    "        self._hour = hour\n",
    "        self._minute = minute\n",
    "        self._second = second\n",
    "\n",
    "    def run(self):\n",
    "        \"\"\"走字\"\"\"\n",
    "        while second<=60:\n",
    "            self._second += 1\n",
    "        # to be continued\n",
    "\n",
    "    def show(self):\n",
    "        \"\"\"显示时间\"\"\"\n",
    "        return '%02d:%02d:%02d' % \\\n",
    "               (self._hour, self._minute, self._second)\n",
    "\n",
    "def main():\n",
    "    clock = Clock(23, 59, 58)\n",
    "    while True:\n",
    "        print(clock.show())\n",
    "        sleep(1)\n",
    "        clock.run()\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    main()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "王大锤正在玩飞行棋.\n",
      "王大锤正在玩斗地主.\n"
     ]
    }
   ],
   "source": [
    "class Person(object):\n",
    "    def __init__(self, name, age):\n",
    "        self._name = name\n",
    "        self._age = age\n",
    "\n",
    "    # 访问器 - getter方法\n",
    "    @property\n",
    "    def name(self):\n",
    "        return self._name\n",
    "\n",
    "    # 访问器 - getter方法\n",
    "    @property\n",
    "    def age(self):\n",
    "        return self._age\n",
    "\n",
    "    # 修改器 - setter方法\n",
    "    @age.setter\n",
    "    def age(self, age):\n",
    "        self._age = age\n",
    "\n",
    "    def play(self):\n",
    "        if self._age <= 16:\n",
    "            print('%s正在玩飞行棋.' % self._name)\n",
    "        else:\n",
    "            print('%s正在玩斗地主.' % self._name)\n",
    "\n",
    "def main():\n",
    "    person = Person('王大锤', 12)\n",
    "    person.play()\n",
    "    person.age = 22\n",
    "    person.play()\n",
    "    # AttributeError: can't set attribute\n",
    "    # person.name = '白元芳'  \n",
    "\n",
    "if __name__ == '__main__':\n",
    "    main()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "初三的王大锤正在学习数学.\n",
      "王大锤只能观看《熊出没》.\n",
      "骆昊老叫兽正在讲Python程序设计.\n",
      "骆昊正在观看爱情动作片.\n"
     ]
    }
   ],
   "source": [
    "class Person(object):\n",
    "    \"\"\"人\"\"\"\n",
    "\n",
    "    def __init__(self, name, age):\n",
    "        self._name = name\n",
    "        self._age = age\n",
    "\n",
    "    @property\n",
    "    def name(self):\n",
    "        return self._name\n",
    "\n",
    "    @property\n",
    "    def age(self):\n",
    "        return self._age\n",
    "\n",
    "    @age.setter\n",
    "    def age(self, age):\n",
    "        self._age = age\n",
    "\n",
    "    def play(self):\n",
    "        print('%s正在愉快的玩耍.' % self._name)\n",
    "\n",
    "    def watch_av(self):\n",
    "        if self._age >= 18:\n",
    "            print('%s正在观看爱情动作片.' % self._name)\n",
    "        else:\n",
    "            print('%s只能观看《熊出没》.' % self._name)\n",
    "class Student(Person):\n",
    "    \"\"\"学生\"\"\"\n",
    "\n",
    "    def __init__(self, name, age, grade):\n",
    "        super().__init__(name, age)\n",
    "        self._grade = grade\n",
    "\n",
    "    @property\n",
    "    def grade(self):\n",
    "        return self._grade\n",
    "\n",
    "    @grade.setter\n",
    "    def grade(self, grade):\n",
    "        self._grade = grade\n",
    "\n",
    "    def study(self, course):\n",
    "        print('%s的%s正在学习%s.' % (self._grade, self._name, course))\n",
    "class Teacher(Person):\n",
    "    \"\"\"老师\"\"\"\n",
    "\n",
    "    def __init__(self, name, age, title):\n",
    "        super().__init__(name, age)\n",
    "        self._title = title\n",
    "\n",
    "    @property\n",
    "    def title(self):\n",
    "        return self._title\n",
    "\n",
    "    @title.setter\n",
    "    def title(self, title):\n",
    "        self._title = title\n",
    "\n",
    "    def teach(self, course):\n",
    "        print('%s%s正在讲%s.' % (self._name, self._title, course))\n",
    "\n",
    "\n",
    "def main():\n",
    "    stu = Student('王大锤', 15, '初三')\n",
    "    stu.study('数学')\n",
    "    stu.watch_av()\n",
    "    t = Teacher('骆昊', 38, '老叫兽')\n",
    "    t.teach('Python程序设计')\n",
    "    t.watch_av()\n",
    "\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    main()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "旺财: 汪汪汪...\n",
      "凯蒂: 喵...喵...\n",
      "大黄: 汪汪汪...\n"
     ]
    }
   ],
   "source": [
    "from abc import ABCMeta, abstractmethod\n",
    "\n",
    "\n",
    "class Pet(object, metaclass=ABCMeta):\n",
    "    \"\"\"宠物\"\"\"\n",
    "\n",
    "    def __init__(self, nickname):\n",
    "        self._nickname = nickname\n",
    "\n",
    "    @abstractmethod\n",
    "    def make_voice(self):\n",
    "        \"\"\"发出声音\"\"\"\n",
    "        pass\n",
    "class Dog(Pet):\n",
    "    \"\"\"狗\"\"\"\n",
    "\n",
    "    def make_voice(self):\n",
    "        print('%s: 汪汪汪...' % self._nickname)\n",
    "\n",
    "\n",
    "class Cat(Pet):\n",
    "    \"\"\"猫\"\"\"\n",
    "\n",
    "    def make_voice(self):\n",
    "        print('%s: 喵...喵...' % self._nickname)\n",
    "\n",
    "\n",
    "def main():\n",
    "    pets = [Dog('旺财'), Cat('凯蒂'), Dog('大黄')]\n",
    "    for pet in pets:\n",
    "        pet.make_voice()\n",
    "\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    main()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "ename": "AttributeError",
     "evalue": "'Point' object has no attribute 'y'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[1;32mD:\\temp/ipykernel_19844/2678973662.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m     50\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     51\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0m__name__\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;34m'__main__'\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 52\u001b[1;33m     \u001b[0mmain\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32mD:\\temp/ipykernel_19844/2678973662.py\u001b[0m in \u001b[0;36mmain\u001b[1;34m()\u001b[0m\n\u001b[0;32m     42\u001b[0m     \u001b[0mp1\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mPoint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m5\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     43\u001b[0m     \u001b[0mp2\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mPoint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 44\u001b[1;33m     \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mp1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     45\u001b[0m     \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mp2\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     46\u001b[0m     \u001b[0mp2\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmove_by\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mD:\\temp/ipykernel_19844/2678973662.py\u001b[0m in \u001b[0;36m__str__\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m     36\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     37\u001b[0m     \u001b[1;32mdef\u001b[0m \u001b[0m__str__\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 38\u001b[1;33m         \u001b[1;32mreturn\u001b[0m \u001b[1;34m'(%s, %s)'\u001b[0m \u001b[1;33m%\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mstr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mstr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     39\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     40\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mAttributeError\u001b[0m: 'Point' object has no attribute 'y'"
     ]
    }
   ],
   "source": [
    "from math import sqrt\n",
    "\n",
    "\n",
    "class Point(object):\n",
    "\n",
    "    def __init__(self, x=0, y=0):\n",
    "        \"\"\"初始化方法\n",
    "        \n",
    "        :param x: 横坐标\n",
    "        :param y: 纵坐标\n",
    "        \"\"\"\n",
    "        self.x = x\n",
    "\n",
    "    def move_to(self, x, y):\n",
    "        \"\"\"移动到指定位置\n",
    "        \n",
    "        :param x: 新的横坐标\n",
    "        \"param y: 新的纵坐标\n",
    "        \"\"\"\n",
    "        self.y = y\n",
    "\n",
    "    def move_by(self, dx, dy):\n",
    "        \"\"\"移动指定的增量\n",
    "        \n",
    "        :param dx: 横坐标的增量\n",
    "        \"param dy: 纵坐标的增量\n",
    "        \"\"\"\n",
    "        self.x += dx\n",
    "\n",
    "    def distance_to(self, other):\n",
    "        \"\"\"计算与另一个点的距离\n",
    "        \n",
    "        :param other: 另一个点\n",
    "        \"\"\"\n",
    "        return sqrt()\n",
    "\n",
    "    def __str__(self):\n",
    "        return '(%s, %s)' % (str(self.x), str(self.y))\n",
    "\n",
    "\n",
    "def main():\n",
    "    p1 = Point(3, 5)\n",
    "    p2 = Point()\n",
    "    print(p1)\n",
    "    print(p2)\n",
    "    p2.move_by(-1, 2)\n",
    "    print(p2)\n",
    "    print(p1.distance_to(p2))\n",
    "\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    main()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.9.7 ('base')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "2dbe5485cf12282196b80a8ac362415f1d4830d1445e2229f35f94c570ef032e"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
